/**************************************************************
 *
 * Copyright (c) 2008, ******, All Rights Reserved.
 *
 * 名 称:
 *		acct_ta_cancel.cpp
 * 位 置:
 *		src/biz/order/acct_ta_cancel.cpp
 * 描 述:
 *		基金账户销户
 * 备 注:
 *		无
 * 修 改:
 *		2008-10-9  Simon   - 创建
 *
 **************************************************************/

#include <string>
#include <iostream>
#include "occi.h"
#include "pub/str.h"
#include "pub/log.h"
#include "biz/base_order_acct.h"

using namespace std;
using namespace oracle::occi;

class OrderAcctTACancel : public BaseOrderAcct
{
public:
	String taCode;			//TA代码
	String taAccountID;		//基金帐号

private:
	String taAcctStatus; 	//基金账户状态

public:
	//构造函数
	OrderAcctTACancel();

	//析构函数
	~OrderAcctTACancel();

public:
	//检查输入参数
	virtual void checkData();

	//初始化
	virtual void init();

	//检查功能权限
	virtual void checkPriv();

	//检查条件是否满足
	virtual void checkCondition();

	//功能处理
	virtual void process();

private:
	//写入基金账户数据
	void writeAcctTA();

	//写入账户委托数据
	void writeOrderAcct();
};

//----------------------------------------------
//	构造函数
//----------------------------------------------
OrderAcctTACancel::OrderAcctTAOpen()
{
	returnCode	= "0000";
	returnMsg	= "基金账户销户成功";
}

//----------------------------------------------
//	析构函数
//----------------------------------------------
OrderAcctTACancel::~OrderAcctTACancel()
{
}

//----------------------------------------------
//	检查输入参数
//----------------------------------------------
void OrderAcctTACancel::checkData()
{
	BaseOrderAcct::checkData();

	const char* pattern = "^[0-9]{2,3}$";
	if (!taCode.match(pattern))
	{
		Log::throwError("TA代码不合法");
	}

	pattern = "^[0-9A-Z]{,12}$";
	if (!taAccountID.match(pattern))
	{
		Log::throwError("基金帐号不合法");
	}
}

//----------------------------------------------
//	初始化
//----------------------------------------------
void OrderAcctTACancel::init()
{
	int count = 0;

	BaseOrderAcct::init();

	Statement* stmt = conn->createStatement();
	ResultSet* rs = 0;
	try
	{
		//检查基金帐号是否存在
		stmt->setSQL(" \
			select count(*) \
			from AcctTA \
			where transAccountID = :transAccountID \
			and taCode = :taCode \
			and taAccountID = :taAccountID"
		);
		stmt->setString(1, transAccountID);
		stmt->setString(2, taCode);
		stmt->setString(3, taAccountID);
		rs = stmt->executeQuery();
		rs->next();
		count = rs->getInt(1);
		if (count <= 0)
		{
			Log::throwError("基金帐号不存在");
		}

		//获取基金帐号状态
		stmt->setSQL(" \
			select taAcctStatus \
			from AcctTA \
			where transAccountID=:transAccountID \
			and taCode = :taCode \
			and taAccountID = :taAccountID"
		);
		stmt->setString(1, transAccountID);
		stmt->setString(2, taCode);
		stmt->setString(3, taAccountID);
		rs = stmt->executeQuery();
		rs->next();
		taAcctStatus = rs->getString(1);

		stmt->closeResultSet(rs);
		conn->terminateStatement(stmt);
	}
	catch (...)
	{
		stmt->closeResultSet(rs);
		conn->terminateStatement(stmt);
		throw ;
	}
}

//----------------------------------------------
//	检查功能权限
//----------------------------------------------
void OrderAcctTACancel::checkPriv()
{
	BaseOrderAcct::checkPriv();

	//检查基金账户状态是否允许执行该业务
	priv->serviceCode 	= serviceCode;
	priv->taAcctStatus	= taAcctStatus;
	priv->checkAcctTA();
}

//----------------------------------------------
//	检查条件是否满足
//----------------------------------------------
void OrderAcctTACancel::checkCondition()
{
	BaseOrderAcct::checkCondition();

	Statement* stmt = conn->createStatement();
	ResultSet* rs = 0;
	try
	{
		//检查基金帐号是否已存在
		stmt->setSQL(" \
			select count(*) \
			from AcctTA \
			where transAccountID = :transAccountID \
			and taCode = :taCode \
			and taAcctStatus not in ('2')");
		stmt->setString(1, transAccountID);
		stmt->setString(2, taCode);
		rs = stmt->executeQuery();
		rs->next();
		int count = rs->getInt(1);
		if (count > 0)
		{
			Log::throwError("基金账户已存在.");
		}
		stmt->closeResultSet(rs);
		conn->terminateStatement(stmt);
	}
	catch (...)
	{
		stmt->closeResultSet(rs);
		conn->terminateStatement(stmt);
		throw ;
	}
}

//----------------------------------------------
//	功能处理
//----------------------------------------------
void OrderAcctTACancel::process()
{
    //写入基金账户数据
    writeAcctTA();

    //写入账户委托数据
    writeOrderAcct();
}

//----------------------------------------------
//	写入基金账户数据
//----------------------------------------------
void OrderAcctTACancel::writeAcctTA()
{
	Statement* stmt = conn->createStatement();
	try
	{
		//写入基金账户数据
		stmt->setSQL(" \n\
			insert into AcctTA \n\
			( \n\
				transAccountID,				--交易帐号 \n\
				taAccountID,				--基金帐号 \n\
				taCode,						--TA代码 \n\
				freezingDate,				--冻结截至日期 \n\
				frozenCause,				--冻结原因 \n\
				taAcctStatus,				--基金账户状态 \n\
				taAcctOpenDate,				--基金账户开户确认日期 \n\
				taAcctCancelDate,			--基金账户销户确认日期 \n\
				taAcctFreezeDate,			--基金账户冻结确认日期 \n\
				taAcctUnfreezeDate,			--基金账户解冻确认日期 \n\
				summary						--备注 \n\
			) \n\
			values \n\
			( \n\
				:transAccountID,			--交易帐号 \n\
				'',							--基金帐号 \n\
				:taCode,					--TA代码 \n\
				'',							--冻结截至日期 \n\
				'',							--冻结原因 \n\
				'3',						--基金账户状态 3-开户待确认 \n\
				'',							--基金账户开户确认日期 \n\
				'',							--基金账户销户确认日期 \n\
				'',							--基金账户冻结确认日期 \n\
				'',							--基金账户解冻确认日期 \n\
				''							--备注 \n\
			)"
		);
		stmt->setString(1, transAccountID);
		stmt->setString(2, taCode);
		stmt->executeUpdate();
		conn->terminateStatement(stmt);
	}
	catch (...)
	{
		conn->terminateStatement(stmt);
		throw ;
	}
}

//----------------------------------------------
//	写入账户委托数据
//----------------------------------------------
void OrderAcctTACancel::writeOrderAcct()
{
	Statement* stmt = conn->createStatement();
	ResultSet* rs = 0;
	ResultSet* rs2 = 0;
	try
	{
        //生成委托流水
        serial->tradeDate = tradeDate;
        serial->genOrderSerial();

        //获取交易账户数据
        stmt->setSQL(" \
			select \
        		deliverType, \
        		deliverWay \
			from AcctTrans \
			where transAccountID = :transAccountID"
      	);
        stmt->setString(1, transAccountID);
        rs = stmt->executeQuery();
        rs->next();

        //获取客户账户数据
        stmt->setSQL(" \
			select \
        		invstType, \
        		invstName, \
        		invstAbbr, \
        		nationality, \
        		certType, \
        		certNo, \
        		certValidFrom, \
        		certValidTo, \
        		shSecAccountID, \
        		szSecAccountID, \
        		address, \
        		postCode, \
        		telNo, \
        		homeTelNo, \
        		officeTelNo, \
        		mobileTelNo, \
        		faxNo, \
        		email, \
        		birthday, \
        		sex, \
        		education, \
        		vocation, \
        		income, \
        		instType, \
        		instReprName, \
        		instReprCertType, \
        		instReprCertNo, \
        		instReprCertValidFrom, \
        		instReprCertValidTo \
			from AcctCust \
			where custAccountID = :custAccountID"
		);
		stmt->setString(1, custAccountID);
		rs2 = stmt->executeQuery();
		rs2->next();

		//写入账户委托数据
		stmt->setSQL(BaseOrderAcct::writeOrderAcctSQL);
		stmt->setString(1, serial->orderSerialNo); 	//委托流水
		stmt->setString(2, serviceCode); 			//功能码
		stmt->setString(3, businessCode); 			//业务码
		stmt->setString(4, acceptMethod); 			//受理方式
		stmt->setString(5, channelCode); 			//渠道编号
		stmt->setString(6, regionCode); 			//地区编号
		stmt->setString(7, branchCode); 			//网点编号
		stmt->setString(8, opID); 					//柜员编号
		stmt->setString(9, custAccountID); 			//客户帐号
		stmt->setString(10, transAccountID); 		//交易帐号
		stmt->setString(11, ""); 					//基金帐号
		stmt->setString(12, taCode); 				//TA代码
		stmt->setString(13, "0"); 					//多渠道开户标志
		stmt->setString(14, ""); 					//冻结截至日期
		stmt->setString(15, ""); 					//冻结原因
		stmt->setString(16, ""); 					//原委托流水
		stmt->setString(17, ""); 					//原申请流水
		stmt->setString(18, rs2->getString(1)); 	//投资者类型
		stmt->setString(19, rs2->getString(2)); 	//投资者人名
		stmt->setString(20, rs2->getString(3)); 	//投资者简称
		stmt->setString(21, rs2->getString(4)); 	//投资者国籍
		stmt->setString(22, rs2->getString(5)); 	//投资者证件类型
		stmt->setString(23, rs2->getString(6)); 	//投资者证件号码
		stmt->setString(24, rs2->getString(7));		//投资者证件有效期起始日期
		stmt->setString(25, rs2->getString(8)); 	//投资者证件有效期截至日期
		stmt->setString(26, rs2->getString(9)); 	//上交所证券帐号
		stmt->setString(27, rs2->getString(10)); 	//深交所证券帐号
		stmt->setString(28, rs2->getString(11)); 	//通讯地址
		stmt->setString(29, rs2->getString(12)); 	//邮政编码
		stmt->setString(30, rs2->getString(13)); 	//电话号码
		stmt->setString(31, rs2->getString(14)); 	//住址电话
		stmt->setString(32, rs2->getString(15));	//办公电话
		stmt->setString(33, rs2->getString(16)); 	//手机号码
		stmt->setString(34, rs2->getString(17));	//传真号码
		stmt->setString(35, rs2->getString(18)); 	//E-MAIL地址
		stmt->setString(36, rs2->getString(19)); 	//出生日期
		stmt->setString(37, rs2->getString(20)); 	//性别
		stmt->setString(38, rs2->getString(21));	//教育程度
		stmt->setString(39, rs2->getString(22)); 	//职业代码
		stmt->setString(40, rs2->getString(23)); 	//年收入
		stmt->setString(41, rs2->getString(24)); 	//机构类型
		stmt->setString(42, rs2->getString(25)); 	//法人姓名
		stmt->setString(43, rs2->getString(26)); 	//法人证件类型
		stmt->setString(44, rs2->getString(27)); 	//法人证件号码
		stmt->setString(45, rs2->getString(28)); 	//法人证件有效期起始日期
		stmt->setString(46, rs2->getString(29)); 	//法人证件有效期截至日期
		stmt->setString(47, ""); 					//银行代码
		stmt->setString(48, ""); 					//银行全称
		stmt->setString(49, ""); 					//银行帐号户名
		stmt->setString(50, ""); 					//银行帐号卡号
		stmt->setString(51, ""); 					//银行帐号验证
		stmt->setString(52, instTransName); 		//经办人姓名
		stmt->setString(53, instTransCertType); 	//经办人证件类型
		stmt->setString(54, instTransCertNo); 		//经办人证件号码
		stmt->setString(55, instTransCertValidFrom);//经办人证件有效期起始日期
		stmt->setString(56, instTransCertValidTo); 	//经办人证件有效期截至日期
		stmt->setString(57, ""); 					//经办人联系电话
		stmt->setString(58, ""); 					//经办人移动电话
		stmt->setString(59, rs->getString(1)); 		//对帐单寄送选择
		stmt->setString(60, rs->getString(2)); 		//对账单寄送方式
		stmt->setString(61, ""); 					//交易方式
		stmt->setString(62, ""); 					//风险承受能力
		stmt->setString(63, "0"); 					//委托预约标志
		stmt->setString(64, ""); 					//委托预约日期
		stmt->setString(65, "0"); 					//是否需要授权
		stmt->setString(66, ""); 					//授权标志(0-未授权 1-授权通过 2-授权不通过)
		stmt->setString(67, ""); 					//授权操作员
		stmt->setString(68, ""); 					//授权日期
		stmt->setString(69, ""); 					//授权时间
		stmt->setString(70, "0"); 					//委托发起标志
		stmt->setString(71, "1"); 					//委托状态
		stmt->setString(72, orderDate); 			//委托日期
		stmt->setString(73, orderTime); 			//委托时间
		stmt->setString(74, summary); 				//备注
		stmt->executeUpdate();
		stmt->closeResultSet(rs);
		conn->terminateStatement(stmt);
	}
	catch (...)
	{
		stmt->closeResultSet(rs);
		conn->terminateStatement(stmt);
		throw ;
	}
}
